package sendGoodsRecord

import (
	"context"
	"errors"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"gorm.io/gorm"
	"insighttracking/apps/admin/auth"
	"insighttracking/common/enum"
	"insighttracking/common/utils"
	"insighttracking/query/dao"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"net/http"

	"insighttracking/apps/admin/internal/svc"
	"insighttracking/apps/admin/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type CreateSendGoodsRecordApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewCreateSendGoodsRecordApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *CreateSendGoodsRecordApiLogic {
	hostname, _ := os.Hostname()
	return &CreateSendGoodsRecordApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *CreateSendGoodsRecordApiLogic) CreateSendGoodsRecordApi(req *types.CreateSendGoodsRecordReq) (resp string, err error) {
	// todo: add your logic here and delete this line
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}
	for _, item := range req.IdList {
		ordersEntity, err := service.OrdersService.GetByIdApi(l.ctx, item)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return "", errors.New("传递的订单号错误")
		}
		if ordersEntity.Status > 10 {
			return "", errors.New("当前订单里包括已发货")
		}
		_, err = service.StoreSortingService.GetStoreSortingByOrderIdApi(l.ctx, item)
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return "", errors.New("传递的订单id包括了未分拣出库的单,请重新选择")
		}
	}
	sortingEntities, err := service.StoreSortingService.GetStoreSortingByOrderIdListApi(l.ctx, req.IdList)
	var sortingMap = make(map[int64]*model.StoreSortingEntity)
	if err == nil && len(sortingEntities) > 0 {
		sortingMap = k.ToMap(sortingEntities, func(item *model.StoreSortingEntity) (int64, *model.StoreSortingEntity) {
			return item.OrdersID, item
		})
	}
	sortingIdList := k.Map(sortingEntities, func(item *model.StoreSortingEntity, index int) int64 {
		return item.ID
	})
	storeSortingDetailList, err := service.StoreSortingDetailService.GetStoreSortingDetailByStoreSortingIdListApi(l.ctx, sortingIdList)
	var storeSortingDetailGroup = make(map[int64][]*model.StoreSortingDetailEntity)
	if err == nil && len(storeSortingDetailList) > 0 {
		storeSortingDetailGroup = k.GroupBy(storeSortingDetailList, func(item *model.StoreSortingDetailEntity) int64 {
			return item.StoreSortingID
		})
	}
	// 创建发货数据
	tx := dao.Use(l.svcCtx.MysqlDb).Begin()
	for _, item := range req.IdList {
		sortingEntity := sortingMap[item]
		var sendGoodsRecordData = model.SendGoodsRecordEntity{
			OrderNo:      utils.GenerateTodayOrderNo(l.svcCtx.RedisDb, "FJCK"), // 订单流水号
			EnterpriseID: accountInfo.EnterpriseId,                             // 关联到enterprise表主键id
			CustomerID:   sortingEntity.CustomerID,                             // 客户id,关联到enterprise_customer表主键id
			TotalAmount:  sortingEntity.TotalAmount,                            // 订单金额
			TotalCount:   sortingEntity.TotalCount,                             // 订单商品数量
			WarehouseID:  sortingEntity.WarehouseID,                            // 发货单号,关联到warehouse表主键id
			OrdersID:     sortingEntity.OrdersID,                               // 关联到订单表id,orders表主键id
			OperateName:  sortingEntity.OperateName,                            // 制单员
			OperateID:    sortingEntity.OperateID,                              // 制单员id,关联到员工表
			Remark:       sortingEntity.Remark,                                 // 备注
		}
		if err = service.SendGoodsRecordService.CreateApi(l.ctx, tx, &sendGoodsRecordData); err != nil {
			if err = tx.Rollback(); err != nil {
				return "", err
			}
			return "", errors.New("创建失败")
		}
		// 创建明细
		detailEntities, isOk := storeSortingDetailGroup[sortingEntity.ID]
		var sendGoodsRecordDetailData = make([]*model.SendGoodsRecordDetailEntity, 0)
		if isOk {
			for _, detailEntity := range detailEntities {
				sendGoodsRecordDetailData = append(sendGoodsRecordDetailData, &model.SendGoodsRecordDetailEntity{
					SendGoodsRecordID:       sendGoodsRecordData.ID,               // 分拣单store_sorting主键id
					SpuID:                   detailEntity.SpuID,                   // 商品,关联到spu表主键id
					SnapshotSpuName:         detailEntity.SnapshotSpuName,         // 快照商品名称
					SnapshotProductImageURL: detailEntity.SnapshotProductImageURL, // 快照产品图片
					SnapshotSpuType:         detailEntity.SnapshotSpuType,         // 快照商品类型,0表示基础商品,1表示加工商品
					SnapshotUnit:            detailEntity.SnapshotUnit,            // 快照单位
					SnapshotCategoryID:      detailEntity.SnapshotCategoryID,      // 快照分类id
					SnapshotCategory:        detailEntity.SnapshotCategory,        // 快照分类
					LossRate:                detailEntity.LossRate,                // 快照损耗率
					OrdersCount:             detailEntity.OrdersCount,             // 下单数量
					SnapshotPrice:           detailEntity.SnapshotPrice,           // 商品单价
					OutboundCount:           detailEntity.OutboundCount,           // 出库数量
					OperateName:             detailEntity.OperateName,             // 出库员
					OperateID:               detailEntity.OperateID,               // 出库员id,关联到员工表
					Remark:                  detailEntity.Remark,                  // 备注
				})
				//changeCount := detailEntity.OutboundCount.Add(detailEntity.LossCount)
				// 扣减库存
				//if err = service.SpuInventoryService.ReduceInventoryApi(l.ctx, tx, accountInfo.EnterpriseId, sortingEntity.WarehouseID, detailEntity.SpuID, changeCount); err != nil {
				//	if err = tx.Rollback(); err != nil {
				//		return "", err
				//	}
				//	return "", errors.New("操作失败")
				//}
				//// 库存记录
				//if err = service.InventRecordService.CreateInventRecordApi(l.ctx, tx, &model.InventoryRecordEntity{
				//	EnterpriseID: accountInfo.EnterpriseId,                    // 关联到enterprise表主键id
				//	SpuID:        detailEntity.SpuID,                          // 商品主键,关联到spu表主键id
				//	Types:        1,                                           // 类型,0表示入库,1表示出库
				//	Source:       0,                                           // 来源,0表示正常出入口,10表示盘点报损报溢,20表调拨
				//	WarehouseID:  sortingEntity.WarehouseID,                   // 仓库id,关联到warehouse表主键id
				//	ChangeCount:  changeCount,                                 // 变动数量
				//	Price:        detailEntity.SnapshotPrice,                  // 单价
				//	Amount:       changeCount.Mul(detailEntity.SnapshotPrice), // 金额
				//}); err != nil {
				//	if err = tx.Rollback(); err != nil {
				//		return "", err
				//	}
				//	return "", errors.New("操作失败")
				//}
			}
		}
		if err = service.SendGoodsRecordDetailService.CreateBatchApi(l.ctx, tx, sendGoodsRecordDetailData); err != nil {
			if err = tx.Rollback(); err != nil {
				return "", err
			}
			return "", errors.New("操作失败")
		}
		if err = service.OrdersService.ModifyStatusByIdApi(l.ctx, tx, []int64{item}, enum.OrdersAlreadyShippedEnum); err != nil {
			if err = tx.Rollback(); err != nil {
				return "", err
			}
			return "", errors.New("操作失败")
		}
		if err = service.OrdersDetailService.ModifyStatusByOrderIdListApi(l.ctx, tx, item, enum.OrdersAlreadyShippedEnum); err != nil {
			if err = tx.Rollback(); err != nil {
				return "", err
			}
			return "", errors.New("操作失败")
		}
	}
	if err = tx.Commit(); err != nil {
		return "", errors.New("操作失败")
	}
	return "操作成功", nil
}
